﻿using Dapper;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.Caching.Memory;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using YAKEJI.Abp.Database;
using YAPACS.BusinessObjects.Managements.Devices;
using YAPACS.BusinessObjects.Managements.Exams;
using YAPACS.BusinessObjects.Managements.InterfaceServices;
using YAPACS.Organizations;
using YAPACS.RisServer.Services.Dtos;
using YAPACS.Workflows;

namespace YAPACS.RisServer.Workflows.ExamApply;

public class GetExamApply : WorkflowBase, IGetExamApply, ITransientDependency
{
    private readonly IDatabaseConnectionProvider _connectionProvider;
    private readonly IRepository<ApplyDepartment, Guid> _applyDepartmentRepository;
    private readonly ICurrentUserOrganization _currentUserOrganization;
    private readonly IRepository<Department, Guid> _departmentRepository;
    public GetExamApply(IDatabaseConnectionProvider connectionProvider, IRepository<ApplyDepartment, Guid> applyDepartmentRepository,
        ICurrentUserOrganization currentUserOrganization, IRepository<Department, Guid> departmentRepository)
    {
        _connectionProvider = connectionProvider;
        _applyDepartmentRepository = applyDepartmentRepository;
        _currentUserOrganization = currentUserOrganization;
        _departmentRepository = departmentRepository;
    }

    protected override async Task<WorkflowOutput> InvokeCoreAsync(WorkflowInput input)
    {
        return new WorkflowOutput { Success = true };
        const string key = "InterfaceService";
        if (input.ContainsKey(key) && input.GetValueOrDefault(key) is InterfaceService interfaceService)
        {
            var number = input.GetValueOrDefault("Number") as string;
            var userData = input.GetValueOrDefault("Input") as Dictionary<string, object>;
            var department = await _departmentRepository.GetAsync(_currentUserOrganization.DepartmentId.Value);
            var deviceTypes = department.GetDeviceTypes().Select(e => e.Modality).ToList();
            var examApplies = await GetExamApplyItems(number, userData, interfaceService.Name, deviceTypes);
            //如果接口或者视图/存储过程已经存在，需要解析性别/年龄单位
            return new WorkflowOutput
            {
                Success = true,
                Data = new DataGridDto()
                {
                    Rows = examApplies,
                    TotalCount = examApplies.Count
                }
            };
        }
        return new WorkflowOutput
        {
            Success = false,
            Error = "无接口调用"
        };
    }

    /// <summary>
    /// 数据库
    /// </summary>
    /// <param name="number"></param>
    /// <param name="userData"></param>
    private async Task<List<ExamApplyDto>> GetExamApplyItems(string number, Dictionary<string, object> userData, string patientType, List<string> deviceTypes)
    {
        string condition = " where IsRegister=0 and PatientType=:patientType ";
        if (userData.Keys.Count > 0)
        {
            if (!userData.ContainsKey("applyTimeRange"))
            {
                userData.Add("applyTimeRange", string.Join(",", [DateTime.Today.AddDays(-2).ToString("yyyy-MM-dd"), DateTime.Today.ToString("yyyy-MM-dd")]));

            }
            for (int i = 0; i < userData.Count; i++)
            {
                var item = userData.ElementAt(i);
                // 就诊卡号
                if (item.Key.Equals("medicalCardNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and MedicalCardNumber=:{item.Key}";
                    }
                }
                // 姓名
                if (item.Key.Equals("name"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and Name=:{item.Key}";
                    }
                }
                //门诊号
                if (item.Key.Equals("outPatientNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and OutPatientNumber=:{item.Key}";
                    }
                }
                // 住院号
                if (item.Key.Equals("inPatientNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and InPatientNumber=:{item.Key}";
                    }
                }
                // 体检号
                if (item.Key.Equals("physicalExamNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and PhysicalExamNumber=:{item.Key}";
                    }
                }
                // 联系方式
                if (item.Key.Equals("phoneNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and PhoneNumber=:{item.Key}";
                    }
                }
                //日期范围
                if (item.Key.Equals("applyTimeRange"))
                {
                    var applyTimeRange = item.Value as string;
                    if (string.IsNullOrWhiteSpace(applyTimeRange))
                    {
                        applyTimeRange = string.Join(",", [DateTime.Today.AddDays(-2).ToString("yyyy-MM-dd"), DateTime.Today.ToString("yyyy-MM-dd")]);
                    }
                    var timeRange = applyTimeRange.Split(',');
                    var startTime = DateTime.Parse(timeRange[0]).Date;
                    var endTime = DateTime.Parse(timeRange[1]).AddDays(1).Date;
                    if (!userData.ContainsKey("startTime"))
                    {
                        userData.Add("startTime", startTime);
                    }
                    if (!userData.ContainsKey("endTime"))
                    {
                        userData.Add("endTime", endTime);
                    }
                    condition += $" and (ApplyTime >= :startTime and ApplyTime < :endTime)";
                }

                // 证件号码
                if (item.Key.Equals("idCardNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and IdCardNumber=:{item.Key}";
                    }
                }
                // 申请科室
                if (item.Key.Equals("applyDepartments"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var applyDepartmentIds = value.Split(',').Select(Guid.Parse);
                        var applyDepartments = await _applyDepartmentRepository.GetListAsync(e => applyDepartmentIds.Contains(e.Oid));
                        var applyDepartmentOuterCodes = applyDepartments.Select(e => e.OuterCode).ToList();
                        condition += $" and ApplyDepartmentCode in :applyDepartmentOuterCodes";
                        if (!userData.ContainsKey("applyDepartmentOuterCodes"))
                        {
                            userData.Add("applyDepartmentOuterCodes", applyDepartmentOuterCodes);
                        }
                    }
                }
                // 医保卡号
                if (item.Key.Equals("medicalInsuranceNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and MedicalInsuranceNumber=:{item.Key}";
                    }
                }
            }
        }
        else if (string.IsNullOrWhiteSpace(number))
        {
            var startTime = DateTime.Today.AddDays(-2);
            var endTime = DateTime.Today.AddDays(1);
            if (!userData.ContainsKey("startTime"))
            {
                userData.Add("startTime", startTime);
            }
            if (!userData.ContainsKey("endTime"))
            {
                userData.Add("endTime", endTime);
            }
            condition += $" and (ApplyTime >= :startTime and ApplyTime < :endTime)";
        }
        else
        {
            if (!userData.ContainsKey("number"))
            {
                userData.Add("number", number);
            }
            condition += $" and (IdCardNumber=:number or MedicalInsuranceNumber=:number or MedicalCardNumber=:number or PhoneNumber=:number or ApplyNumber=:number or MedicalRecordNumber=:number or PhysicalExamNumber=:number or OutPatientNumber=:number or InPatientNumber=:number or InPatientArea=:number or WardNumber=:number or BedNumber=:number)";
        }
        if (deviceTypes.Count > 0)
        {
            if (!userData.ContainsKey("deviceTypes"))
            {
                userData.Add("deviceTypes", deviceTypes);
            }
            condition += @" and DeviceType in :deviceTypes";
        }
        if (!userData.ContainsKey("patientType"))
        {
            userData.Add("patientType", patientType);
        }
        string dbFile = Path.Combine(@"c:\yapacs\mock-data", @"ExamApply.db");
        string connectionString = $@"Data Source={dbFile};";
        using var connection = new SqliteConnection(connectionString);
        SQLitePCL.Batteries.Init();
        string sql = @"select * from ExamApply" + condition;
        var list = await connection.QueryAsync<ExamApplyDto>(sql, userData);
        return list.ToList();
    }
    private async Task<List<ExamApplyDto>> GetExamApplyItemsView(string number, Dictionary<string, object> userData, string patientType, List<string> deviceTypes)
    {
        string condition = " where PatientType=@patientType ";
        if (userData.Keys.Count > 0)
        {
            if (!userData.ContainsKey("applyTimeRange"))
            {
                userData.Add("applyTimeRange", string.Join(",", [DateTime.Today.AddDays(-2).ToString("yyyy-MM-dd"), DateTime.Today.ToString("yyyy-MM-dd")]));

            }
            for (int i = 0; i < userData.Count; i++)
            {
                var item = userData.ElementAt(i);
                // 就诊卡号
                if (item.Key.Equals("medicalCardNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and MedicalCardNumber=@{item.Key}";
                    }
                }
                // 姓名
                if (item.Key.Equals("name"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and Name=@{item.Key}";
                    }
                }
                //门诊号
                if (item.Key.Equals("outPatientNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and OutPatientNumber=@{item.Key}";
                    }
                }
                // 住院号
                if (item.Key.Equals("inPatientNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and InPatientNumber=@{item.Key}";
                    }
                }
                // 体检号
                if (item.Key.Equals("physicalExamNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and PhysicalExamNumber=@{item.Key}";
                    }
                }
                // 联系方式
                if (item.Key.Equals("phoneNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and PhoneNumber=@{item.Key}";
                    }
                }
                //日期范围
                if (item.Key.Equals("applyTimeRange"))
                {
                    var applyTimeRange = item.Value as string;
                    if (string.IsNullOrWhiteSpace(applyTimeRange))
                    {
                        applyTimeRange = string.Join(",", [DateTime.Today.AddDays(-2).ToString("yyyy-MM-dd"), DateTime.Today.ToString("yyyy-MM-dd")]);
                    }
                    var timeRange = applyTimeRange.Split(',');
                    var startTime = DateTime.Parse(timeRange[0]).Date;
                    var endTime = DateTime.Parse(timeRange[1]).AddDays(1).Date;
                    if (!userData.ContainsKey("startTime"))
                    {
                        userData.Add("startTime", startTime);
                    }
                    if (!userData.ContainsKey("endTime"))
                    {
                        userData.Add("endTime", endTime);
                    }
                    condition += $" and (ApplyTime >= @startTime and ApplyTime < @endTime)";
                }

                // 证件号码
                if (item.Key.Equals("idCardNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and IdCardNumber=@{item.Key}";
                    }
                }
                // 申请科室
                if (item.Key.Equals("applyDepartments"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        var applyDepartmentIds = value.Split(',').Select(Guid.Parse);
                        var applyDepartments = await _applyDepartmentRepository.GetListAsync(e => applyDepartmentIds.Contains(e.Oid));
                        var applyDepartmentOuterCodes = applyDepartments.Select(e => e.OuterCode).ToList();
                        condition += $" and ApplyDepartmentCode in @applyDepartmentOuterCodes";
                        if (!userData.ContainsKey("applyDepartmentOuterCodes"))
                        {
                            userData.Add("applyDepartmentOuterCodes", applyDepartmentOuterCodes);
                        }
                    }
                }
                // 医保卡号
                if (item.Key.Equals("medicalInsuranceNumber"))
                {
                    var value = item.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        condition += $" and MedicalInsuranceNumber=@{item.Key}";
                    }
                }
            }
        }
        else if (string.IsNullOrWhiteSpace(number))
        {
            var startTime = DateTime.Today.AddDays(-2);
            var endTime = DateTime.Today.AddDays(1);
            if (!userData.ContainsKey("startTime"))
            {
                userData.Add("startTime", startTime);
            }
            if (!userData.ContainsKey("endTime"))
            {
                userData.Add("endTime", endTime);
            }
            condition += $" and (ApplyTime >= @startTime and ApplyTime < @endTime)";
        }
        else
        {
            if (!userData.ContainsKey("number"))
            {
                userData.Add("number", number);
            }
            condition += $" and (IdCardNumber=@number or MedicalInsuranceNumber=@number or MedicalCardNumber=@number or PhoneNumber=@number or ApplyNumber=@number or MedicalRecordNumber=@number or PhysicalExamNumber=@number or OutPatientNumber=@number or InPatientNumber=@number or InPatientArea=@number or WardNumber=@number or BedNumber=@number)";
        }
        if (deviceTypes.Count > 0)
        {
            if (!userData.ContainsKey("deviceTypes"))
            {
                userData.Add("deviceTypes", deviceTypes);
            }
            condition += @" and DeviceType in @deviceTypes";
        }
        if (!userData.ContainsKey("patientType"))
        {
            userData.Add("patientType", patientType);
        }
        const string connectionString = @"Server=192.168.2.82;Initial Catalog=HIS;User Id=sa;Password=pacs@1234;TrustServerCertificate=True";
        using var connection = _connectionProvider.GetDbConnection(connectionString, DatabaseType.SqlServer);
        string sql = @"select * from pacs_view_exam_apply_item" + condition;
        var list = await connection.QueryAsync<ExamApplyDto>(sql, userData);
        return list.ToList();
    }
}
